home *** CD-ROM | disk | FTP | other *** search
/ Power Programmierung 2 / Power-Programmierung CD 2 (Tewi)(1994).iso / c / library / dos / communic / pcmail / main / kpres.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-06-05  |  5.0 KB  |  209 lines

  1. /*++
  2. /* NAME
  3. /*    kpres
  4. /* SUMMARY
  5. /*    k-protocol presentation layer
  6. /* PACKAGE
  7. /*    uucp across thenet
  8. /* SYNOPSIS
  9. /*    #include "kp.h"
  10. /*
  11. /*    kopen(fd)
  12. /*    int fd;
  13. /*
  14. /*    kwrite(fd,buf,len)
  15. /*    int fd,len;
  16. /*    char *buf;
  17. /*
  18. /*    kread(fd,buf,len)
  19. /*    int fd,len;
  20. /*    char *buf;
  21. /*
  22. /*    kclose(fd)
  23. /*    int fd;
  24. /* DESCRIPTION
  25. /*    This section contains functions that imitate standard unix
  26. /*    unbuffered i/o facilities. A status code of FAIL is returned when
  27. /*    the network partner wants to terminate the protocol, or when the
  28. /*    the transmission error rate is excessive.
  29. /*
  30. /*    Eight-bit data bytes are transported as harmless six-bit data bytes
  31. /*    in the ASCII range 32 through 95. This introduces an overhead of 33%.
  32. /*    For textfiles, this is hardly worse than kermit (typical overhead 
  33. /*    10 %). For binary files the overhead is much less than with kermit 
  34. /*    (typical overhead 60%).
  35. /*
  36. /*    Kopen() sets up the terminal characteristics of the specified file
  37. /*    descriptors (no echo, raw, tandem). Always returns zero status.
  38. /*
  39. /*    Kwrite() attempts to send the bytes in buf. A zero-length buffer 
  40. /*    should be written to indicate an end-of-file condition. Return status: 
  41. /*    the number of bytes requested, or FAIL.
  42. /*
  43. /*    Kread() attempts to read the requested number of bytes. Status code:
  44. /*    the number of bytes actually read, or FAIL. A read of zero bytes
  45. /*    normally indicates an end-of-file condition (see kwrite).
  46. /*
  47. /*    Kclose() sends a protocol abort sequence to the network partner.
  48. /*    This function should be called to terminate the k protocol driver
  49. /*    at the other end, or to confirm reception of a protocol abort sequence.
  50. /*    Kclose always returns zero exit status.
  51. /*
  52. /*    The function kfail() is called by the strategy layer functions to 
  53. /*    indicate protocol failure or termination.
  54. /* FUNCTIONS AND MACROS
  55. /*    kwproto, krproto, kclsproto
  56. /* BUGS
  57. /*    Zero byte read/writes are a clumsy way to handle end-of-files. 
  58. /*    They have been implemented for the sake of compatibility with uucico.
  59. /* AUTHOR(S)
  60. /*    Wietse Venema
  61. /*    Eindhoven University of Technology
  62. /*    Department of Mathematics and Computer Science
  63. /*    Den Dolech 2, P.O. Box 513, 5600 MB Eindhoven, The Netherlands
  64. /* CREATION DATE
  65. /*    Mon Feb  3 11:14:13 MET 1986
  66. /* LAST MODIFICATION
  67. /*    90/01/22 13:01:57
  68. /* VERSION/RELEASE
  69. /*    2.1
  70. /*--*/
  71.  
  72. #ifdef unix
  73. # ifdef    SIII
  74. #   include <termio.h>
  75. # else
  76. #   include <sgtty.h>
  77. # endif
  78. #endif
  79. #include <setjmp.h>
  80. #include "kp.h"
  81.  
  82. static jmp_buf Failbuf;
  83.  
  84. kfail()
  85. {
  86.     longjmp(Failbuf,TRUE);
  87. }
  88.  
  89. kopen(fd)
  90. int fd;
  91. {
  92. #ifdef unix
  93. # ifdef SIII
  94.     struct termio ttymode;
  95.  
  96.     ioctl(fd,TCGETA,&ttymode);
  97.     ttymode.c_iflag = IXOFF|IXON|ISTRIP;
  98.     ttymode.c_cc[VMIN] = 1;
  99.     ttymode.c_cc[VTIME] = 0;
  100.     ioctl(fd,TCSETA,&ttymode);
  101. # else
  102.     struct sgttyb ttymode;
  103.  
  104.     gtty(fd,&ttymode);
  105.     ttymode.sg_flags |= (TANDEM|RAW);
  106.     ttymode.sg_flags &= ~(ECHO|CBREAK);
  107.     stty(fd,&ttymode);
  108. # endif
  109. #else
  110.     xioctl(1);
  111. #endif
  112.     return 0;
  113. }
  114.  
  115. kwrite(fd,buf,len)
  116. int fd;
  117. register char *buf;
  118. register int len;
  119. {
  120.     static char  packbuf[MAXPACKSIZ];
  121.     static char *packptr = packbuf;
  122.     register int c,i,rest,shift;
  123.  
  124.     /* set error trap */
  125.  
  126.     if (setjmp(Failbuf))
  127.     return FAIL;
  128.  
  129.     /* if 'end of data' send null packet */
  130.  
  131.     if (len <= 0) {
  132.     kwproto(fd,NULLP,0);
  133.     return 0;
  134.  
  135.     /* expand 3 eight-bit bytes to four six-bit bytes */
  136.  
  137.     } else {
  138.     for (rest = shift = i = 0; i < len; shift = (shift+STEP)%OUT,i++) {
  139.  
  140.         c = *buf++ & 0377;                /* No sign extension */
  141.         *packptr++ = tosix(rest|(c << shift));    /* Assemble byte */
  142.         rest = (c >> (OUT-shift));            /* Save unused bits */
  143.  
  144.         if (shift == (OUT-STEP)) {            /* At byte boundary? */
  145.         *packptr++ = tosix(rest);        /* Make 'fourth' byte */
  146.         rest = 0;                /* No unused bits now */
  147.         if (packptr-packbuf > PACKSIZ-4) {    /* Check packet size */
  148.             kwproto(fd,packbuf,packptr-packbuf);
  149.             packptr = packbuf;
  150.         }
  151.         }
  152.     }
  153.     if (shift) {                    /* Any bits left? */
  154.         *packptr++ = tosix(rest);            /* Put them there */
  155.     }
  156.     if (packptr > packbuf) {            /* Flush buffer */
  157.         kwproto(fd,packbuf,packptr-packbuf);    /* Ship it off */
  158.         packptr = packbuf;
  159.     }
  160.     return i;
  161.     }
  162. }
  163.  
  164. kread(fd,buf,len)
  165. int fd;
  166. char *buf;
  167. int len;
  168. {
  169.     static char packbuf[MAXPACKSIZ] = "";
  170.     static char *packptr = packbuf;
  171.     static int  packsiz = 0;
  172.     register int i,c;
  173.     static int shift,rest;
  174.  
  175.     /* set error trap */
  176.  
  177.     if (setjmp(Failbuf))
  178.     return FAIL;
  179.  
  180.     /* read packet if buffer is empty */
  181.  
  182.     if (packsiz <= 0) {
  183.     krproto(fd,packptr = packbuf,&packsiz);
  184.     rest = shift = 0;
  185.     }
  186.  
  187.     /* unpack (remainder of) buffer; return 0 if empty packet received */
  188.  
  189.     for (i = 0; (i < len) && packsiz--; shift = (shift+STEP)%IN) 
  190.     {
  191.     c = unsix(*packptr++);
  192.     if (shift)
  193.         buf[i++] = (rest | (c << (IN-shift)));
  194.     rest = (c >> shift);
  195.     }
  196.     return i;
  197. }
  198.  
  199. kclose(fd)
  200. int fd;
  201. {
  202.     /* not here - pass job to the lower layer that understands packet types */
  203.  
  204.     kclsproto(fd);
  205.     return 0;
  206. }
  207.  
  208.  
  209.